/*
 * Copyright (C) 2009, 2010, B3log Team
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.b3log.nide.action.websocket;

import java.io.IOException;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import org.b3log.nide.model.WebSocketData;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocket.Outbound;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Output socket.
 *
 * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
 * @version 1.0.0.3, Mar 10, 2011
 */
public final class OutputSocket implements WebSocket, Observer {

    /**
     * Logger.
     */
    private static final Logger LOGGER =
            Logger.getLogger(OutputSocket.class.getName());
    /**
     * Outbound.
     */
    private Outbound outbound;
    /**
     * Http servlet request.
     */
    private HttpServletRequest request;

    @Override
    public void update(final Observable o, final Object arg) {
        send(arg.toString());
    }

    /**
     * Sends the specified line of text.
     *
     * @param line the specified line of text
     */
    public void send(final String line) {
        try {
            outbound.sendMessage(line);
        } catch (final IOException e) {
            LOGGER.log(Level.SEVERE, e.getMessage(), e);
        }
    }

    @Override
    public void onConnect(final Outbound outbound) {
        LOGGER.log(Level.FINE, "{0} onConnect", getClass().getSimpleName());
        this.outbound = outbound;
    }

    @Override
    public void onMessage(final byte frame, final String data) {
        LOGGER.log(Level.FINE, "{0} onMessage(), [data={1}]",
                   new Object[]{getClass().getSimpleName(), data});

        try {
            final JSONObject requestJSONObject = new JSONObject(data);
            if (requestJSONObject.has(WebSocketData.WEB_SOCKET_GREETING)) {
                LOGGER.log(Level.FINER, "Output alive[sessionId={0}].",
                           request.getSession(false).getId());
            }
        } catch (final JSONException e) {
            LOGGER.log(Level.SEVERE, e.getMessage(), e);
        }
    }

    @Override
    public void onMessage(final byte frame, final byte[] data,
                          final int offset, final int length) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void onDisconnect() {
        LOGGER.log(Level.FINE, "{0} onDisconnect", getClass().getSimpleName());
    }

    /**
     * Sets the http servlet request.
     *
     * @param request the new http servlet request
     */
    public void setRequest(final HttpServletRequest request) {
        this.request = request;
    }
}
